#if 0
#include <buola/buola.h>
#include <buola/cv/czerosegm.h>
#include <buola/cv/opencv.h>
#include <buola/cv/harris.h>
#include <buola/cv/algorithms.h>

namespace buola { namespace cvi {

CZeroSegm::CZeroSegm()
    :   mMethod(METHOD_STANDARD)
    ,   mForegroundRange(16)

    width(0), height(0), count(0), mode(ZeroSegm::Standard), verbose(false), active(false), foregroundRange(16), shmData(nullptr)
{ 
}
 
CZeroSegm::~CZeroSegm()
{
}

float CZeroSegm::DispSegment(Image<float> &dimg, Image<float> &cut, float mind, float maxd, float xsiz)
{
  int w = dimg.GetWidth();
  int h = dimg.GetHeight();
  assert(w==cut.GetWidth() && h==cut.GetHeight());
  float *dimd = dimg.GetData();
  float *cutd = cut.GetData();
  float dsiz = maxd - mind;

  float meanx = 0.0; 
  float meany = 0.0;
  float meand = 0.0;
  int total = 0;
  for (int y=0;y<h;y++) {
    for (int x=0;x<w;x++) {
      int p = y*w + x;
      if (dimd[p]>=mind && dimd[p]<=maxd) {
        meanx += x;
        meany += y;
        meand += dimd[p];
        total++;
      } 
    }  
  }
  if (total) {
    meanx /= total;
    meany /= total;
    meand /= total;  
  }
  int minx, miny, maxx, maxy;
  for (int i=0;i<5;i++) {
    minx = (int)(meanx - xsiz/2);
    if (minx<0) minx = 0;
    maxx = (int)(meanx + xsiz/2);
    if (maxx>w) maxx = w;
    miny = (int)(meany - xsiz/2);
    if (miny<0) miny = 0;
    maxy = (int)(meany + xsiz/2);
    if (maxy>h) maxy = h;
    mind = meand - dsiz/2;
    if (mind<0.0) mind = 0.0;
    maxd = meand + dsiz/2;
    meanx = 0.0; 
    meany = 0.0; 
    meand = 0.0;
    total = 0;
    for (int y=miny;y<maxy;y++) {
      for (int x=minx;x<maxx;x++) {
        int p = y*w + x;
        if (dimd[p]>=mind && dimd[p]<=maxd) {
          meanx += x;
          meany += y;
          meand += dimd[p];
          total++;
        }
      }
    }
    if (total) {
      meanx /= total;
      meany /= total;
      meand /= total;
    }
  }
  minx = (int)(meanx - xsiz/2);
  maxx = (int)(meanx + xsiz/2);
  miny = (int)(meany - xsiz/2);
  maxy = (int)(meany + xsiz/2);
  for (int y=0;y<h;y++) {
    for (int x=0;x<w;x++) {
      int p = y*w + x;
      if (dimd[p]>=mind && dimd[p]<=maxd && x>=minx && x<maxx && 
          y>=miny && y<maxy) 
        cutd[p] = 10.0; //(unsigned char)(255*(dimd[p]-mind) / dsiz);
      else if (dimd[p]<0.0) 
        cutd[p] = 0.0;
      else 
        cutd[p] = 0.0;
    } 
  }
  return meand;
}

int ZeroSegmImpl::KeepLargestComp(Image<unsigned char> &mask, int minsize, int expxsize, int expysize) 
{
  unsigned char *masd = mask.GetData();
  int w = mask.GetWidth();
  int h = mask.GetHeight();
  for (int i=0;i<w*h;i++) 
    masd[i] = (masd[i]>0 ? 255 : 0);
  int compnum = 0;
  int compsiz = 0;
  int largnum = -1;
  int largsiz = 0;
  std::vector<int> positions;
  int minx = (w - expxsize)/2;
  int maxx = (w + expxsize)/2;
  int miny = (h - expysize)/2;
  int maxy = (h + expysize)/2;
  for (int y=miny;y<maxy;y++) {
    for (int x=minx;x<maxx;x++) {
      if (masd[y*w+x]==255) {
        compnum++;
        masd[y*w+x] = compnum;
        positions.push_back(y*w+x);
        compsiz = 0;
	int mnx = x;
	int mxx = x;
	int mny = y;
	int mxy = y;
        while (!positions.empty()) {
          int pos = positions.back();
          compsiz++;
          positions.pop_back();
          int xp = pos % w;
          int yp = pos / w;
	  mnx = (xp<mnx ? xp : mnx);
	  mxx = (xp>mxx ? xp : mxx);
	  mny = (yp<mny ? yp : mny);
	  mxy = (yp>mxy ? yp : mxy);
          if (xp<w-5 && masd[pos+1]==255) {
            masd[pos+1] = compnum;
            positions.push_back(pos+1);
          }
          if (xp>4 && masd[pos-1]==255) {
            masd[pos-1] = compnum;
            positions.push_back(pos-1);
          }
          if (yp<h-5 && masd[pos+w]==255) {
            masd[pos+w] = compnum;
            positions.push_back(pos+w);
          }
          if (yp>4 && masd[pos-w]==255) {
            masd[pos-w] = compnum;
            positions.push_back(pos-w);
          }
        }
	//msg_info() << mnx << " " << mxx << " " << mny << " " << mxy << "\n";
        if (compsiz>largsiz && mnx<w/2 && mxx>w/2 && mny<h/2 && mxy>h/2) {
          largsiz = compsiz;
          largnum = compnum;
        }
      }
    }
  } 
  //msg_info() << largsiz << " " << minsize << "\n";
  int xc = w/2, yc = h/2;
  if (largsiz>minsize) // Keep only largest
    for (int i=0;i<w*h;i++) 
      masd[i] = (masd[i]==largnum ? 255 : 0);
  else if (largsiz>0) {               // Keep a rectangle
    if (largsiz>minsize/10) {
      int xtot = 0, ytot = 0;
      for (int y=0;y<h;y++) 
        for (int x=0;x<w;x++) 
          if (masd[y*w+x]==largnum) {
            xtot += x;
            ytot += y;
          }
      xc = xtot / largsiz;
      yc = ytot / largsiz;
    }
    int minx = xc - expxsize / 2;
    minx = (minx<0 ? 0 : minx);
    int maxx = xc + expxsize / 2;
    maxx = (maxx>w ? w : maxx);
    int miny = yc - expysize / 2;
    miny = (miny<0 ? 0 : miny);
    int maxy = yc + expysize / 2;
    maxy = (maxy>h ? h : maxy);
    for (int y=0;y<miny;y++) 
      for (int x=0;x<w;x++) masd[y*w+x] = 0;
    for (int y=miny;y<maxy;y++) {
      for (int x=0;x<minx;x++) masd[y*w+x] = 0;
      for (int x=minx;x<maxx;x++) masd[y*w+x] = 255;
      for (int x=maxx;x<w;x++) masd[y*w+x] = 0;
    }
    for (int y=maxy;y<h;y++) 
      for (int x=0;x<w;x++) masd[y*w+x] = 0;
  }
  //msg_info() << "Sizes: " << largsiz << " " << minsize << "\n";
  return largsiz;
}

void ZeroSegmImpl::PrepareLogProbs(float mind, float maxd, int drange, float std, float *probs)
{
  const float p_fg = 0.3;      // foreground 
  const float p_bg = 1.0-p_fg; // background 
  const float p_tl_fg = 0.2;   // textureless foreground
  const float p_mm_fg = 0.2;   // mismatch foreground
  const float p_co_fg = 1.0 - p_tl_fg - p_mm_fg; // correct foreground
  const float p_tl_bg = 0.22;   // textureless background
  const float p_mm_bg = 0.3;   // mismatch background
  const float p_co_bg = 1.0 - p_tl_bg - p_mm_bg; // correct background
  const float p_fp_fg = 0.05;  // false positive foreground;

  //mind += std;
  //maxd -= std;
  float *p_d_fg = probs;
  float *p_d_bg = new float[drange+2];
  p_d_fg[0] = p_tl_fg;
  p_d_fg[1] = p_mm_fg;
  p_d_bg[0] = p_tl_bg;
  p_d_bg[1] = p_mm_bg;
  float tot = 0.0;
  for (int d=0;d<drange;d++) {
    if (d>mind && d<maxd) 
      p_d_fg[d+2] = 1.0;
    else if (d<=mind) 
      p_d_fg[d+2] = exp(-(d-mind)*(d-mind)/(2.0*std*std));
    else 
      p_d_fg[d+2] = exp(-(d-maxd)*(d-maxd)/(2.0*std*std));
    tot += p_d_fg[d+2];
  }
  tot = (1.0-p_fp_fg) / tot;
  for (int d=0;d<drange;d++) {
    p_d_bg[d+2] = p_co_fg / drange;
    p_d_fg[d+2] = p_d_fg[d+2] * tot + p_fp_fg / drange;
  }
  for (int d=-2;d<drange;d++) {
    p_d_fg[d+2] = log(p_d_fg[d+2] / p_d_bg[d+2]);
    //msg_info() << d << " " << p_d_fg[d+2] << "\n";
  }
  delete [] p_d_bg;
} 

void ZeroSegmImpl::WaterSegment(Image<unsigned char> &limg, Image<float> &disp, 
				float mind, float maxd, int drange, float std, 
				Image<float> &cut, float* table_probs)
{
  int w = limg.GetWidth();
  int h = limg.GetHeight();
  Image<float> timg(w, h);
  Copy(limg, timg);
  LowPass(timg, timg);  
  LowPass(timg, timg); 
  Segmentation<float> segm(timg, 1.5, 300);
  segm.Execute();
  float *probs = new float[drange+2];
  PrepareLogProbs(mind, maxd, drange, std, probs);
  float *disd = disp.GetData();
  float *cutd = cut.GetData();
  if (table_probs!=nullptr)
    for (int i=0;i<w*h;i++) {
      float p_fg_table = 0.05;
      float p_fg_no_table = 0.50;
      float p_bg_table = 1.0 - p_fg_table;
      float p_bg_no_table = 1.0 - p_fg_no_table;
      float p_table = table_probs[i];
      float p_fg = p_fg_table*p_table + p_fg_no_table*(1.0 - p_table);
      float p_bg = p_bg_table*p_table + p_bg_no_table*(1.0 - p_table);
      cutd[i] = probs[(int)disd[i]+2] + log(p_fg/p_bg);
    }
  else
    for (int i=0;i<w*h;i++) 
      cutd[i] = probs[(int)disd[i]+2];
  
  segm.RegionAverage(cut, cut, true);
  //cut.Store("cut.pgm", true, false);
  for (int i=0;i<w*h;i++)  
    cutd[i] = (cutd[i]>0.0 ? 4.0 : 0.0);
  delete [] probs;
} 
   
void BlurHistogram(float *hist, int variance)
{
  float temp[128];
  for (int i=0;i<variance;i++) {
    temp[0] = 6*hist[0] + 4*(hist[1] + hist[127]) + (hist[2] + hist[126]);
    temp[1] = 6*hist[1] + 4*(hist[2] + hist[0]) + (hist[3] + hist[127]);
    for (int j=2;j<126;j++)
      temp[j] = 6*hist[j] + 4*(hist[j+1] + hist[j-1]) + (hist[j+2] + hist[j-2]);
    temp[126] = 6*hist[126] + 4*(hist[127] + hist[125]) + (hist[0] + hist[124]);
    temp[127] = 6*hist[127] + 4*(hist[0] + hist[126]) + (hist[1] + hist[125]);
    for (int j=0;j<128;j++)
      hist[i] = temp[i] / 16.0f;
  }
}

void ZeroSegmImpl::CollectHistograms(Image<float> &cut, Image<unsigned char> hue, float *probf)
{
  float histf[128], histb[128];
  int w = hue.GetWidth();
  int h = hue.GetHeight();
  unsigned char *hued = hue.GetData();
  float *segd = cut.GetData();
  // collect histograms
  for (int i=0;i<128;i++) {
    histf[i] = 1.0f;
    histb[i] = 1.0f;
  }
  for (int y=0;y<h;y++) {
    int p = y*w;
    for (int x=0;x<w;x++,p++) {
      if (segd[p]>0.0)
	histf[hued[p]] ++;
      else
	histb[hued[p]] ++;
    }
  }
  // normalize histograms
  float sumf = 0.0f;
  float sumb = 0.0f;
  for (int i=0;i<128;i++) {
    sumf += histf[i];
    sumb += histb[i];
  }
  msg_info() << sumf << " " << sumb << "\n";
  sumf = 1.0f / sumf;
  sumb = 1.0f / sumb;
  for (int i=0;i<128;i++) {
    histf[i] *= sumf;
    histb[i] *= sumb;
  }
  // blur histograms
  BlurHistogram(histf, 10);
  BlurHistogram(histb, 10);
  for (int i=0;i<128;i++) 
    probf[i] = histf[i]/(histf[i] + 3*histb[i]);
}

void ZeroSegmImpl::WaterHueSegment(Image<unsigned char> &clim, Image<unsigned char> &limg, 
				   Image<float> &disp, float mind, float maxd, int drange, 
				   float std, Image<float> &cut, float *table_probs)
{
  int w = limg.GetWidth();
  int h = limg.GetHeight();
  Image<float> timg(w, h);
  Copy(limg, timg);
  LowPass(timg, timg);  
  LowPass(timg, timg); 
  Segmentation<float> segm(timg, 1.5, 300);
  segm.Execute();
  Image<unsigned char> hue(w, h);
  MSR clk1, clk2;
  clk1.getTSC();
  HueModels::RGBToHue(clim, hue);
  float *probs = new float[drange+2];
  PrepareLogProbs(mind, maxd, drange, std, probs);
  for (int i=0;i<drange+2;i++)
    probs[i] = exp(probs[i]);
  float *disd = disp.GetData();
  float *cutd = cut.GetData(); 
  if (table_probs!=nullptr)
    for (int i=0;i<w*h;i++) {
      float p_fg_table = 0.05;
      float p_fg_no_table = 0.50;
      float p_bg_table = 1.0 - p_fg_table;
      float p_bg_no_table = 1.0 - p_fg_no_table;
      float p_table = table_probs[i];
      float p_fg = p_fg_table*p_table + p_fg_no_table*(1.0 - p_table);
      float p_bg = p_bg_table*p_table + p_bg_no_table*(1.0 - p_table);
      cutd[i] = probs[(int)disd[i]+2] + log(p_fg/p_bg);
    }
  else
    for (int i=0;i<w*h;i++) 
      cutd[i] = probs[(int)disd[i]+2];
  
  segm.RegionAverage(cut, cut, true);
  //cut.Store("cut.pgm", true, false);
  clk2.getTSC();
  float probf[128], histf[128], histb[128];
  unsigned char *hued = hue.GetData();
  for (int loop=0;loop<4;loop++) {
    clk1.getTSC();
    // collect histograms
    for (int i=0;i<128;i++) {
      histf[i] = 1.0f;
      histb[i] = 1.0f;
    }
    for (int y=0;y<h;y++) {
      int p = y*w;
      for (int x=0;x<w;x++,p++) {
	float ep = cutd[p];
	//msg_info() << "ep " << ep << "\n";
	float pf = ep / (1.0f + ep);
	float pb = 1.0f - pf;
	histf[hued[p]] += pf;
	histb[hued[p]] += pb;
      }
    }
    // normalize histograms
    float sumf = 0.0f;
    float sumb = 0.0f;
    for (int i=0;i<128;i++) {
      sumf += histf[i];
      sumb += histb[i];
    }
    
    for (int i=0;i<128;i++) {
      histf[i] /= sumf;
      histb[i] /= sumb;
    }

    int weight_hue = 2;
    
    // blur histograms
    BlurHistogram(histf, 5);
    BlurHistogram(histb, 5);
    for (int i=0;i<128;i++) 
      probf[i] = histf[i]/histb[i];
    if (table_probs!=nullptr)
      for (int i=0;i<w*h;i++){ 
	cutd[i] = probs[(int)disd[i]+2] * probf[hued[i]] * (1-table_probs[i]);
	//cutd[i] = probs[(int)disd[i]+2] * probf[hued[i]] * (p_fp_fg/table_probs[i]);
      }
    else
      for (int i=0;i<w*h;i++) 
	cutd[i] = probs[(int)disd[i]+2] * probf[hued[i]];
    clk2.getTSC();
  }
  clk1.getTSC();
#if 1 // Dirty approximation assuming IEEE754 floats
  float logvals[32];
  for (int i=0;i<32;i++)
    logvals[i] = log(1.0 + (float)i/32)/log(2.0);
  for (int i=0;i<w*h;i++) {
    int v = *((int *)&cutd[i]);
    cutd[i] = (((v&0x7f800000)>>23) - 0x7f) + logvals[(v>>18) & 0x1f];
  }
#else
  for (int i=0;i<w*h;i++)  
    cutd[i] = log(cutd[i]);
#endif
  clk2.getTSC();
  clk1.getTSC();
  segm.RegionAverage(cut, cut, true);
  for (int i=0;i<w*h;i++)  
    cutd[i] = (cutd[i]>0.0 ? 4.0 : 0.0);
  delete [] probs;
  clk2.getTSC();
}   
   
float ComputeCenterDisp(Image<float> &disp, float center, float range, int radius)
{
  int w = disp.GetWidth();
  int h = disp.GetHeight();
  int minx = w/2 - radius;
  int maxx = w/2 + radius;
  int miny = h/2 - radius;
  int maxy = h/2 + radius;
  for (int i=0;i<5;i++) {
    float mind = center - range/2;
    float maxd = center + range/2;
    float sumi = 0.0f, sumd = 0.0f;
    float *disd = disp.GetData();
    for (int y=miny;y<maxy;y++) {
      int p = y*w + minx;
      for (int x=minx;x<maxx;x++,p++) {
	if (disd[p]>=0.0f && disd[p]>mind && disd[p]<maxd) {
	  sumd += disd[p];
	  sumi += 1.0f;
	}
      }
    }
    if (sumi>0.0f)
      center = sumd / sumi;
    //msg_info() << "Center: " << center << "\n";
  }
  return center;
}

void FindPlanarSurface(Image<float> &disp, float *dst, int range)
{
  int w = disp.GetWidth();
  int h = disp.GetHeight();
  float *dimg = disp.GetData();
  float mindgrady = 0.08;
  // Find dominating disparity for each y-value
  int *hist = new int[h*range];
  int *totals = new int[h];
  for (int y=0;y<h;y++) {
    int *histy = &hist[y*range];
    for (int i=0;i<range;i++) 
      histy[i] = 0;
    for (int x=0;x<w;x++) {
      int d = (int)dimg[y*w + x];
      if (d>=0 && d<range)
	histy[d] ++;
    }
    for (int i=0;i<range-2;i++)
      histy[i] = histy[i] + 2*histy[i+1] + histy[i+2];
    for (int i=range-1;i>1;i--)
      histy[i] = histy[i] + 2*histy[i-1] + histy[i-2];
    totals[y] = 0;
    for (int i=0;i<range;i++)
      totals[y] += histy[i];
  }
  // Find best line using random sampling
  float maxwei = 0.0f; 
  float dgradx = 0.0f, dgrady = 0.0f, dzero = range/2;
  for (int l=0;l<1000;l++) {
    int idx1 = rand()%h;
    int idx2 = rand()%h;
    while (idx1==idx2)
      idx2 = rand()%h;
    if (!totals[idx1] || !totals[idx2])
      continue;
    int cnt1 = rand()%totals[idx1];
    int cnt2 = rand()%totals[idx2];
    int disp1 = 0, disp2 = 0;
    for (int sum1=0;sum1<cnt1;disp1++) 
      sum1 += hist[idx1*range+disp1];
    for (int sum2=0;sum2<cnt2;disp2++) 
      sum2 += hist[idx2*range+disp2];
    disp1--;
    disp2--;
    float dgra = (float)(disp2 - disp1) / (idx2 - idx1);
    float dzer = disp2 - dgra*idx2;
    float sumwei = 0.0f;
    for (int y=0;y<h;y++) {
      for (int dd=-3;dd<=3;dd++) {
	int d = (int)(dgra*y + dzer + 0.5f) + dd;
	if (d<0 || d>=range) 
	  continue;
	float er = d - (dgra*y + dzer);
	sumwei += hist[y*range + d] / (4.0f + er*er);
      }
    }
    if (sumwei>maxwei && dgra>mindgrady) {
      maxwei = sumwei;
      dgrady = dgra;
      dzero = dzer;
    }
  }
  // Improve line (depends only on y) using m-estimator
  for (int l=0;l<3;l++) {
    float syy = 0.0, sy1 = 0.0f, s11 = 0.0f;
    float sdy = 0.0, sd1 = 0.0f;
    for (int y=0;y<h;y++) {
      for (int dd=-3;dd<=3;dd++) {
	int d = (int)(dgrady*y + dzero + 0.5f) + dd;
	if (d<0 || d>=range) 
	  continue;
	float er = d - (dgrady*y + dzero);
	float w = hist[y*range + d] / (4.0f + er*er);
	syy += w*y*y;
	sy1 += w*y;
	s11 += w;
	sdy += w*d*y;
	sd1 += w*d;
      }
    }
    float det = syy*s11 - sy1*sy1;
    dgrady = s11*sdy - sy1*sd1;
    dzero = syy*sd1 - sy1*sdy;
    if (det!=0.0f) {
      dgrady /= det;
      dzero /= det;
    }
  }
  dzero += 0.5f;
  // Improve plane (depends on both x and y) using m-estimator
  for (int l=0;l<3;l++) {
    float sxx = 0.0, sx1 = 0.0f, s11 = 0.0f;
    float sdx = 0.0, sd1 = 0.0f;
    for (int y=0;y<h;y++) {
      for (int x=0;x<h;x++) {
	if (dimg[y*w+x]>=0.0f) {
	  float d = dimg[y*w+x] - dgrady*y;
	  float er = d - (dgradx*x + dzero);
	  float w = 1.0f / (1.0f + er*er);
	  sxx += w*x*x;
	  sx1 += w*x;
	  s11 += w;
	  sdx += w*d*x;
	  sd1 += w*d;
	}
      }
    }
    float det = sxx*s11 - sx1*sx1;
    dgradx = s11*sdx - sx1*sd1;
    dzero = sxx*sd1 - sx1*sdx;
    if (det!=0.0f) {
      dgradx /= det;
      dzero /= det;
    }
  }
#if 1
  for (int y=0;y<h;y++) {
    for (int x=0;x<w;x++) {
      float d = dgradx*x + dgrady*y + dzero;
      int p = y*w + x;
      if (dimg[p]>=0){
	float er = dimg[p] - d;
	dst[p] = exp(-er*er/2.0f);
      } else if (dimg[p]==-2.0f) {
	// if no disparity value given
	dst[p] = 0;
      } else if(dimg[p]==-1.0f){
	dst[p] = 0;
      }
    }
  }
  //Image<float> table(w, h, dst);
  //table.Store("table.pgm", true, false);
  //msg_info() << " " << max_p << ", " << min_p << "\n";
  
#endif
  delete [] hist;
  delete [] totals;
}
  
void ZeroSegmImpl::Update(const img::CView_gray8 &pLeft,const img::CView_gray8 &pRight,
			  float pFovXDif,float pFovYDif,float pFovZRot)
{ 
    int lW=pLeft.Width();
    int lH=pLeft.Height();

    img::CImage_gray8 lMaskOut(pLeft.Size());
    img::CImage_gray32f lDisp(pLeft.Size());
  
    img::CImage_gray8 lMask(pLeft.Size());
    img::CImage_gray8 lLeft2(pLeft.Size());
    img::CImage_gray8 lRight2(pRight.Size());

    copy_pixels(pLeft,lLeft2);
    copy_pixels(pRight,lMask);

    cross_equalize(lLeft2,lMask);

    transform_image(lMask,lRight2,pFovYDif, pFovZRot,1.0f);

    fill_pixels(lDisp,-2.0f);

    int lSpread=32;
    int lWinSize=15;    // NOTE: CalcDisparity() shifts the zero position

    correlation_disparity(lLeft2,lRight2,lDisp,-lSpread,lSpread,lWinSize,1.0,true);
    
  float centerDisp = ComputeCenterDisp(disp, spread, foregroundRange, h/10);
  int totalRange = 2*spread + 1;                   
  float minFgDisp = centerDisp - foregroundRange/2.0f;
  float maxFgDisp = centerDisp + foregroundRange/2.0f;
  float *dst = new float[w/s * h/s];
  Image<float> dstimg(w/s, h/s, dst);
  //Clear(dstimg);
  FindPlanarSurface(disp, dst, totalRange);

  Image<float> cut(w/s, h/s);   
  if (mode==ZeroSegm::GraphCut) {
    FGSegment fgsegment;
    fgsegment.Execute(lim2, disp, centerDisp, foregroundRange, totalRange, 400, 400, cut, dst);
    LowPass3(cut, cut);
  } else {
    float meand = DispSegment(disp, cut, minFgDisp, maxFgDisp, w);
    if (mode==ZeroSegm::WaterShed) {
      WaterSegment(lim2, disp, minFgDisp, maxFgDisp, totalRange, 1.0, cut);
      DericheLowPass<float>(cut, cut, 3.0, true);
    } else if (mode==ZeroSegm::WaterTable) {
      WaterSegment(lim2, disp, minFgDisp, maxFgDisp, totalRange, 1.0, cut, dst);
      DericheLowPass<float>(cut, cut, 3.0, true);
    } else if (mode==ZeroSegm::WaterHue) {
      WaterHueSegment(lref, lim2, disp, minFgDisp, maxFgDisp, totalRange, 1.0, cut, dst);
      clk1.getTSC();
      DericheLowPass<float>(cut, cut, 3.0, true);
      clk2.getTSC();
    } else
      DericheLowPass<float>(cut, cut, 6.0, true);
  }
  Copy(cut, mask);
  KeepLargestComp(mask, 10000, 250, 250);
  Copy(mask, mask_out);
  
  delete [] dst;
}

/*namespace cvi*/ } /*namespace buola*/ }

#endif
